#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=105;
const int M=5005;

int n,m;
struct Edge{
    int to,nex;
    LL w;
    Edge(){}
};
struct Node{
    int s;
    LL w;
    Node(){}
    Node(int s,LL w){
        this->s=s;
        this->w=w;
    }
    bool operator<(const Node& node) const{
        return w>node.w;
    }
};
Edge edges[M];
int head[N];
LL dis[N];
int cnt=1;
void add(int x,int y,LL w){
    edges[cnt].to=y;
    edges[cnt].w=w;
    edges[cnt].nex=head[x];
    head[x]=cnt;
    cnt++;
}

int main(){
    scanf("%d%d",&n,&m);
    memset(head,0,sizeof(head));
    LL inf;
    memset(&inf,0x3f,sizeof(inf));
    for(int i=1;i<=m;i++)
    {
        int op;
        scanf("%d",&op);
        if(op==1){
            int x0,y0;
            LL w0;
            scanf("%d%d%lld",&x0,&y0,&w0);
            add(x0,y0,w0);
            add(y0,x0,w0);
        }
        else if(op==0){
            int s,t;
            scanf("%d%d",&s,&t);
            memset(dis,0x3f,sizeof(dis));
            dis[s]=0;
            priority_queue<Node> que;
            que.push(Node(s,0L));
            while(!que.empty())
            {
                Node node=que.top();
                que.pop();
                int s0=node.s;
                LL w0=node.w;
                if(w0>node.w) continue;
                for(int i=head[s0];i!=0;i=edges[i].nex){
                    int tn = edges[i].to;
                    if(w0+edges[i].w<dis[tn]){
                        dis[tn]=w0+edges[i].w;
                        que.push(Node(tn,dis[tn]));
                    }
                }
            }
            if(dis[t]<inf){
                printf("%lld",dis[t]);
            }
            else{
                printf("-1");
            }
            printf("\n");
        }
    }
    return 0;
}